/*
 * KeyDrv.c
 *
 *  Created on: Apr 13, 2015
 *      Author: mxw
 */
#include "KeyDrv.h"
#include <S3C2440addr.h>
#include "LedDrv.h"
//#include <MainModu.h>
#include <timer.h>
#include <commlib.h>
#include <KeyDetectMod.h>

//key1 -> ENT1/GPF1  GPFCON[3:2]=0 :input
//key2 -> ENT4/GPF4  GPFCON[9:8]=0 :input
//key3 -> ENT2/GPF2  GPFCON[5:4]=0 :input
//key4 -> ENT0/GPF0  GPFCON[1:0]=0 :input

#define GPF1_4_2_0_MASK 0x033F
#define GPF1_4_2_0_AS_INT 0x022A

keyDownInfo_t gkeyDownInfo[4];
void init_key() {
    memset(gkeyDownInfo, 0, sizeof(gkeyDownInfo));
    //step1:config key as interupt
    /*
     * MASK:
     *  00   00   00   11   00   11   11   11
     * GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0
     * 0x  0         3         3         F
     *
     * VAL:
     *  00   00   00   10   00   10   10   10
     * GPF7 GPF6 GPF5 GPF4 GPF3 GPF2 GPF1 GPF0
     * 0x  0         2         2         A
     *
     * */
    rGPFCON &= ~GPF1_4_2_0_MASK;
    rGPFCON |= GPF1_4_2_0_AS_INT;
    
    rGPFUP |= 1; //disable EINT0 pull up
    
    rEXTINT0 &= ~(7); //clear bit0-2   key4
    rEXTINT0 |= 3; //set bit0-2 to 011
    
    
    rEINTMASK &= ~(1 << 4);

    /* rINTMSK:
     * ...  nBATT_FLT INT_CAM EINT8_23 EINT4_7 EINT3 EINT2 EINT1 EINT0
     *bit         7      6        5       4      3     2     1     0
     *mask_vlaue  0      0        0       1      0     1     1     1
     *mask_vlaue  0x17
     */
    rINTMSK &= ~(0x17);

    //step3: set interupt priority
    //config as default..
}

int config_key_as_input(int which_key) {
    if(4 == which_key) {
        rGPFCON &= ~3; //clear GPFCON.bit[0,1]
        rGPFCON |= 0;  //set GPFCON.bit[0,1] to 00
        return 0;
    }
    return -1;
}

int read_key_status(int which_key) {
    int v = 0;
    if(4 != which_key) {
        return KEY_ST_UNKNOWN;//暂未对应
    }
    v = rGPFDAT;
    return (v & 0x1) ? KEY_ST_RELEASED : KEY_ST_PRESSED;
}


int config_key_as_interrupt(int which_key) {
    
    if(4 == which_key) {
        rGPFCON &= ~3; //clear GPFCON.bit[0,1]
        rGPFCON |= 2;  //set GPFCON.bit[0,1] to 10 -> set GPF0 as  EINT[0]
        
        rGPFUP |= 1; //disable EINT0 pull up
        
        rEXTINT0 &= ~(7); //clear bit0-2   key4
        rEXTINT0 |= 3; //set bit0-2 to 011    ->set key4  falling-edge to trigger interrupt
        
        rINTMSK &= ~1;  //remove EINT0(key4) from MASKED
        return 0;
    }
    return -1;
} 

void key4_tm(unsigned short tid) {
    int key_status;
    stop_timer(tid);
    delete_timer(tid);
    rINTMSK &= ~0x1; //enable EINT0 
    // config_key_as_input(4);
    // key_status = read_key_status(4);
    
    if(KEY_ST_PRESSED == key_status) {
        CMsg msg;
        msg.msg_id = CMD_KEY_DOWN;
        msg.data_len = 1;
        msg.data[0] = 4;
        //gKeyDetectMod.sendMsg(&gKeyDetectMod, &msg);
    }
    //config_key_as_interrupt(4);
}

static unsigned int key4_pre_tick = 0;
int on_recv_key_donw_interrupt(int which_key) { //因为键按下和松开时都会有抖动,所以两个时机都会触发本过程
    char buf[32] = {0};
    int key4_tmr_id = 0;
    
    rINTMSK |= 0x1; //disable EINT0 
    key4_tmr_id = get_new_timer(key4_tm);
    start_timer(key4_tmr_id, 50);
    
    gkeyDownInfo[which_key - 1].gkeyDownCnt++;
    gkeyDownInfo[which_key - 1].tick[gkeyDownInfo[which_key - 1].cnt] = get_sys_ticker();
    gkeyDownInfo[which_key - 1].cnt++;
    if(gkeyDownInfo[which_key - 1].cnt >= 10) {
        gkeyDownInfo[which_key - 1].cnt = 0;
    }
    
    CMsg* msg = (CMsg*)&buf[0];
    msg->msg_id = CMD_KEY_DOWN;
    msg->data_len = sizeof(char) + sizeof(unsigned int);
    msg->data[0] = which_key;
    //*(unsigned int*)&msg->data[1] = get_sys_ticker();
    if(get_sys_ticker() - key4_pre_tick > 50) {//1个tick 10ms
        gKeyDetectMod.sendMsg(&gKeyDetectMod, msg); //中断中,不可以直接向可能会发生阻塞的Module发送消息,因此独立出一个KeyDetectModule
    }
    key4_pre_tick = get_sys_ticker();
    return 0;
}

